import os
import threading


def search_files(directory, keywords):
    files = []
    for root, _, filenames in os.walk(directory):
        for filename in filenames:
            if all(keyword in open(os.path.join(root, filename),
                                   encoding='utf-8').read()
                   for keyword in keywords):
                files.append(os.path.join(root, filename))
    return files


def search_files_multithreaded(directory, keywords, max_threads=5):
    files = []
    lock = threading.Lock()

    def search_files_worker():
        nonlocal files
        while True:
            with lock:
                if not directories:
                    break
                directory = directories.pop()
            files += search_files(directory, keywords)

    directories = [
        os.path.abspath(directory) for directory in os.listdir(directory)
    ]
    threads = []
    for i in range(min(max_threads, len(directories))):
        thread = threading.Thread(target=search_files_worker)
        thread.start()
        threads.append(thread)
    for thread in threads:
        thread.join()
    return files
